vite建立react專案feat.vite.config scss、localsConvention、preprocessorOptions
2023-04-26 Wed
不再使用Create React App?
本文提及以下內容
- 不再使用Create React App
- 如何選擇建立React Application in 2023
- 開始建立vite專案
- 使用CSS module
- 經過hash的css class名稱
- 使用駝峰式引用含有dash的css Class 名稱
- 在vite中使用SCSS
- 使用scss module
- 全域共用變數載入至jsx或scss module
目前React官方網站的 Start a New React Project 章節的安裝方式圍繞在SSR或SSG的框架,若單純想建立SPA的話在2023年的今天,傾向使用其他Framework,至於原因可以參考Create React App Alternatives in 2023一文提到幾點
- 緩慢的開發體驗
- 對於市面上受歡迎的工具難以設定
- 有更好的選擇
對於相關議題有興趣的也可以觀看Create React App is Dead?
如何選擇建立React Application in 2023
至於目前React.dev官方網站建立React的方式大多數是SSR(server site render)或SSG(server side generator)的Framework,例如Gatsby.js、Next.js、Remix等等。
對於剛初學React的人在使用學習這些框架的同時可能會包含一些非React相關的東西在該框架當中,因此若只是想單純學習React的人也許就會無法分辨哪些是屬於React,哪些則是屬於該框架,目前社群或者知名Youtuber Kyle在The React Docs Are Wrong (If You Are Trying To Learn React)的影片中則是推薦使用Vite作為學習React的開始
由於vite使用了ES module作為編譯方式使得網頁載入的時候即時編譯,另外採用較少的設置、簡單的設計原則,也支持各種主流的前端框架,對於想要自定義的部分也可以透過插件或是中間件來自行擴充,換句話說相比於Create React App對於伺服器的啟動速度和開發體驗以及建立完畢的初始library相比都是較為輕量及快速的選擇方案。
開始建立vite專案
在terminal中輸入以下指令
npm create vite@latest

如上圖,接下來他會詢問是否安裝,按下Y得以繼續,由於我們的Project的資料夾已經建立了,因此Project Name可以輸入./表示當前路徑,依序選擇Javascript後就建立了基本的資料夾結構。
接下來將會提示指令分別是安裝node module 的相依套件

npm install
npm run dev安裝完畢後src的整個資料夾結構大概會長這樣
│ App.css
│ App.jsx
│ index.css
│ main.jsx
│
└─assets
react.svg接下來會將預設用不到的資源先刪除,依據需求可能會留存assets資料夾,最後資料夾與檔案結構如下
│ App.jsx
│ main.jsx
│
└─assets使用CSS module
為了切分component的CSS作用域,我們使用CSS moudle來達成
因此我們可以建立一個名為app.module.css的檔案
App.jsx
app.module.css
main.jsx建立完畢後我們在app.module.css的檔案內加入以下的class
.title-h1 {
color: red;
}在App.jsx引入
import sytles from "./app.module.css"
const App = () => {
console.log('sytles', sytles);
return (
<div className={sytles['title-h1']}> App</div>
)
}
export default App經過hash的css class名稱
如下圖,我們可以得到從console.log得知藉由css module他會將我們的class名稱加入hash值得name以達到在不同的component當中的className不一樣。

使用駝峰式引用含有dash的css Class 名稱
在撰寫CSS當中我們很常使用dash(也就是-符號)來做為class的name,但是在Javascript當中如果物件的名字包含了dash的話就得撰寫中括號來取值(也就是sytles['title-h1']),因此我們可以藉由vite讓我們引入css的class到jsx更為方便。
在vite.config.js當中設定如下
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
css: {
modules: {
localsConvention: "camelCase",
},
},
}); 藉由加入localsConvention: "camelCase",就能更方便我們在引入的時候使用camelCase的撰寫方式(備註1),實際程式碼如下(備註2)
import styles from "./app.module.css"
const App = () => {
return (
<>
<h1 className={styles.titleH1}>App</h1>
//能使用駝峰式寫法
</>
)
}
export default App備註1 更多設定方式可以參考vite-css module
備註2:官方的vite也有提及到底層的實踐技術是來自於postcss-modules
在vite中使用SCSS
另外為了撰寫巢狀css的方式,我們也會安裝sass在Terminal輸入npm i -D sass
輸入以下指令
npm i -D sass安裝完畢後我們建立global.scss,此時src的資料夾內容如下
App.jsx
global.scss
main.jsx如此一來當我們在撰寫jsx的時候,就能使用scss樣式了,嘗試著global.scss撰寫如下
p {
color: green;
}此時在App.jsx引用global.scss,如下程式碼
import "./global.scss"
const App = () => {
return (
<>
<h1>測試</h1>
<p>
段落文字
</p>
</>
)
}
export default App顯示畫面如下

使用scss module
先前提到css module,在scss中我們一樣可以建立scss module,我們在src當中建立一個app.module.scss,此時src的檔案內容如下
App.jsx
app.module.scss
global.scss
main.jsx一樣在app.module.scss撰寫如下
.title-h1 {
color: red;
}此時我們就能如同先前所提到的css module一樣,在這邊就是使用scss module
import "./global.scss"
import { titleH1 } from "./app.module.scss"
const App = () => {
return (
<>
<h1 className={titleH1}>測試</h1>
<p>
段落文字
</p>
</>
)
}
export default App全域共用變數載入至jsx或scss module
如果我們有些變數或者mixin以往在另外一個檔案要使用,我們會在另外一個檔案使用@use 來載入該檔案。
@use "../../styles/breakpoint";
@use "../../styles/variable";但是有些變數或者mixin是希望在全部的jsx或者scss都讀取的到 此時我們只要在 vite.config.js 設定 preprocessorOptions 就能將該檔案載入在所有的jsx和scss module了
根據官方share otpion-css.preprocessorOptions
範例的設定,就是將$injectedColor這個變數放到每個jsx或者scss module檔案裡面
如下
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `$injectedColor: orange;`,
},
less: {
math: 'parens-division',
},
styl: {
define: {
$specialColor: new stylus.nodes.RGBA(51, 197, 255, 1),
},
},
},
},
})@use "@/src/global.scss"; 這行會被加到每一份 style 中,等同於在每個scss module引入".src/global.scss",如此一來元件就都能取用 global.scss 裡面 scss 的變數
具體程式碼如下
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
css: {
modules: {
localsConvention: "camelCase",
},
preprocessorOptions: {
scss: {
//下面的寫法就不用在每個地方都寫glbal.XXX變數
additionalData: `@use "./src/global.scss" as *;`,
},
},
},
});補充說明
若對於@use為什麼要使用as *的話可以觀看 SCSS Choosing a Namespace 的官方說明